package com.cls.business.controller;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.cls.business.entity.Notice;
import com.cls.business.entity.TopicPlan;
import com.cls.business.factory.NoticeFactory;
import com.cls.business.service.INoticeService;
import com.cls.business.service.ITopicPlanService;
import com.cls.business.strategy.NoticeStrategy;
import com.cls.common.annotation.ControllerEndpoint;
import com.cls.common.enums.DictEnum;
import com.cls.common.controller.BaseController;
import com.cls.common.entity.MyConstant;
import com.cls.common.entity.QueryRequest;
import com.cls.common.entity.ResponseVO;
import com.cls.common.exception.MyException;
import com.cls.common.utils.MyUtil;
import com.cls.common.utils.StringUtils;
import com.cls.system.entity.SysDict;
import com.cls.system.entity.SysFile;
import com.cls.system.service.ISysDictService;
import com.cls.system.service.ISysFileService;
import com.github.pagehelper.PageInfo;
import com.wuwenze.poi.ExcelKit;
import lombok.extern.slf4j.Slf4j;
import lombok.RequiredArgsConstructor;

import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.util.List;
import java.util.Optional;

/**
 * 通知公告 Controller
 *
 * @author weimaomao
 * @date 2020-11-10 09:36:03
 */
@Slf4j
@Validated
@Controller
@RequiredArgsConstructor
public class NoticeController extends BaseController {

    private final INoticeService noticeService;

    private final ISysDictService sysDictService;

    private final ITopicPlanService topicPlanService;

    private final NoticeFactory noticeFactory;

    private final ISysFileService sysFileService;

    /**
     * 通知公告列表页面
     *
     * @return
     */
    @GetMapping(MyConstant.VIEW_PREFIX + "biz/notice")
    public String noticeIndex(Model model) {
        //获取通知类型字典表
        List<SysDict> noticeType = sysDictService.findByParentCode(DictEnum.NOTICE_TYPE.getCode());
        model.addAttribute("noticeType", noticeType);
        return MyUtil.view("business/notice/notice");
    }

    /**
     * 通知公告新增页面
     *
     * @return
     */
    @GetMapping(MyConstant.VIEW_PREFIX + "biz/notice/noticeAdd")
    public String noticeAdd(Model model) {
        //获取通知类型字典表
        List<SysDict> noticeType = sysDictService.findByParentCode(DictEnum.NOTICE_TYPE.getCode());
        model.addAttribute("noticeType", noticeType);
        //查询所有委托课题已评审的计划 展示到前端
        //根据年份、期次、委托课题来获取计划
        List<TopicPlan> topicPlan = topicPlanService.findTopicByClassifyCodeAndNoLevel();
        model.addAttribute("topicPlan", topicPlan);
        List<SysDict> planNos = sysDictService.findByParentCode(DictEnum.PLAN_NO.getCode());
        model.addAttribute("planNos", planNos);
        return MyUtil.view("business/notice/noticeAdd");
    }

    /**
     * 通知公告详情页面
     *
     * @return
     */
    @GetMapping(MyConstant.VIEW_PREFIX + "biz/notice/noticeDetail/{noticeId}")
    public String noticeDetail(@PathVariable Long noticeId, Model model) {
        Notice notice = noticeService.getById(noticeId);
        model.addAttribute("notice", notice);
        //如果是课题征集和课题指南需要关联一下
        if (DictEnum.NOTICE_TYPE_KTZJ.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectBySelectNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        } else if (DictEnum.NOTICE_TYPE_KTZN.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectByApplyNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        } else if (DictEnum.NOTICE_TYPE_JXGG.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectByConcludeNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        }else if (DictEnum.NOTICE_TYPE_RESULT_JXGG.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectNoticeByConcludeFinishNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        }else if (DictEnum.NOTICE_TYPE_NLXGG.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectByPreItemNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        }else if (DictEnum.NOTICE_TYPE_LXGG.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectItemNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        }
        Long itemFileId = notice.getFileId();
        SysFile itemFile;
        if (itemFileId != null) {
            itemFile = Optional.ofNullable(sysFileService.getById(itemFileId)).orElse(new SysFile());
        } else {
            itemFile = new SysFile();
        }
        model.addAttribute("itemFile", itemFile);


        return MyUtil.view("business/notice/noticeDetail");
    }

    /**
     * 通知公告修改页面
     *
     * @return
     */
    @GetMapping(MyConstant.VIEW_PREFIX + "biz/notice/noticeUpdate/{noticeId}")
    public String noticeUpdate(@PathVariable Long noticeId, Model model) {
        Notice notice = noticeService.getById(noticeId);
        model.addAttribute("notice", notice);
        //如果是课题征集和课题指南需要关联一下
        if (DictEnum.NOTICE_TYPE_KTZJ.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectBySelectNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        } else if (DictEnum.NOTICE_TYPE_KTZN.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectByApplyNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        } else if (DictEnum.NOTICE_TYPE_JXGG.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectByConcludeNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        }else if (DictEnum.NOTICE_TYPE_RESULT_JXGG.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectNoticeByConcludeFinishNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        }else if (DictEnum.NOTICE_TYPE_NLXGG.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectByPreItemNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        }else if (DictEnum.NOTICE_TYPE_LXGG.getCode().equals(notice.getTypeCode())) {
            TopicPlan topicPlan = topicPlanService.selectItemNoticeId(noticeId);
            model.addAttribute("topicPlan", topicPlan);
        }
        //获取通知类型字典表
        List<SysDict> noticeType = sysDictService.findByParentCode(DictEnum.NOTICE_TYPE.getCode());
        model.addAttribute("noticeType", noticeType);

        Long itemFileId = notice.getFileId();
        SysFile itemFile;
        if (itemFileId != null) {
            itemFile = Optional.ofNullable(sysFileService.getById(itemFileId)).orElse(new SysFile());
        } else {
            itemFile = new SysFile();
        }
        model.addAttribute("itemFile", itemFile);

        return MyUtil.view("business/notice/noticeUpdate");
    }


    @ControllerEndpoint(operation = "改变通知公告的是否发布", exceptionMessage = "改变通知公告的是否发布失败")
    @PostMapping("notice/publish/{noticeId}")
    @ResponseBody
    @RequiresPermissions("notice:update")
    public ResponseVO changePublishStutas(@PathVariable Long noticeId, Boolean isPublish) {
        noticeService.updateNoticePublish(noticeId, isPublish);
        return ResponseVO.success();
    }

    @GetMapping("notice")
    @ResponseBody
    @RequiresPermissions("notice:list")
    public ResponseVO getAllNotices(Notice notice) {
        return ResponseVO.success(noticeService.findNotices(notice));
    }

    @GetMapping("notice/list")
    @ResponseBody
    @RequiresPermissions("notice:list")
    public ResponseVO noticeList(QueryRequest request, Notice notice) {
        PageInfo<Notice> pageInfo = this.noticeService.findNotices(request, notice);
        return ResponseVO.success(pageInfo);
    }

    @ControllerEndpoint(operation = "新增Notice", exceptionMessage = "新增失败")
    @PostMapping("notice")
    @ResponseBody
    @RequiresPermissions("notice:add")
    public ResponseVO addNotice(@Valid Notice notice) {
        if (StringUtils.isEmpty(notice.getTypeCode())) {
            return ResponseVO.failure("请输入类型");
        }
        sysFileService.updateIsFinish(notice.getFileId(), null);
        NoticeStrategy strategy = noticeFactory.getStrategy(notice.getTypeCode());
        strategy.createNotice(notice);
        return ResponseVO.success();
    }

    @ControllerEndpoint(operation = "修改Notice", exceptionMessage = "修改失败")
    @PostMapping("notice/update")
    @ResponseBody
    @RequiresPermissions("notice:update")
    public ResponseVO updateNotice(Notice notice) {
        Notice noticeOld = this.noticeService.getById(notice.getNoticeId());
        if (noticeOld == null) {
            return ResponseVO.failure("当前id数据不存在");
        }
        if (noticeOld.getIsPublish() != null && noticeOld.getIsPublish()) {
            return ResponseVO.failure("请先取消发布再进行删除！");
        }
        notice.setYear(null);
        sysFileService.updateIsFinish(notice.getFileId(), noticeOld.getFileId());
        this.noticeService.updateNotice(notice);
        return ResponseVO.success();
    }

    @ControllerEndpoint(operation = "修改Notice", exceptionMessage = "导出Excel失败")
    @PostMapping("notice/excel")
    @ResponseBody
    @RequiresPermissions("notice:export")
    public void export(QueryRequest queryRequest, Notice notice, HttpServletResponse response) {
        List<Notice> notices = this.noticeService.findNotices(queryRequest, notice).getList();
        ExcelKit.$Export(Notice.class, response).downXlsx(notices, false);
    }
}
